import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  CloseOutlined,
  DeleteOutlined,
  EditOutlined,
  PlusOutlined,
  SaveOutlined,
} from '@ant-design/icons';
import { Button, DatePicker, Input, InputNumber, Popconfirm, Select, Space, Table, Tooltip } from 'antd';
import { useMemo, useState } from 'react';
import type { FormFieldConfig } from '../types';
import { t } from '../utils';
import './index.css';

// 可编辑表格组件
interface EditableTableProps {
  config?: FormFieldConfig['editTableConfig'];
  value?: any[];
  onChange?: (value: any[]) => void;
  disabled?: boolean;
}

const EditableTable: React.FC<EditableTableProps> = ({ config, value = [], onChange, disabled = false }) => {
  const rowKey = config?.rowKey || 'id';
  const hasPriority = useMemo(() => config?.columns?.some((col) => col.dataIndex === 'priority'), [config?.columns]);

  // 初始化数据源（只在初始化时使用 value）
  const [dataSource, setDataSource] = useState<any[]>(() => {
    const data = value || [];
    if (hasPriority) {
      return data.map((item, index) => ({
        ...item,
        priority: item.priority || index + 1,
      }));
    }
    return data;
  });

  const [editingKey, setEditingKey] = useState<string>('');
  const [originalData, setOriginalData] = useState<Record<string, any>>({});
  const [hasAttemptedSave, setHasAttemptedSave] = useState(false);

  const isEditing = (record: any) => record[rowKey] === editingKey;

  // 更新数据源
  const updateDataSource = (newDataSource: any[]) => {
    setDataSource(newDataSource);
    onChange?.(newDataSource);
  };

  // 清除编辑状态
  const clearEditingState = (key: string) => {
    setEditingKey('');
    setHasAttemptedSave(false);
    const newOriginalData = { ...originalData };
    delete newOriginalData[key];
    setOriginalData(newOriginalData);
  };

  // 验证字段值是否为空
  const isFieldEmpty = (value: any): boolean => {
    return !value || (typeof value === 'string' && value.trim() === '');
  };

  // 验证当前编辑行的必填字段
  const validateEditingRow = (record: any): boolean => {
    if (!config?.columns) return true;

    return config.columns.every((column) => {
      if (!column.required || column.dataIndex === 'priority') return true;
      return !isFieldEmpty(record[column.dataIndex]);
    });
  };

  const handleAdd = () => {
    const newData: any = {
      [rowKey]: `temp_${Date.now()}`,
      ...(hasPriority && { priority: dataSource.length + 1 }),
    };

    const newDataSource = [...dataSource, newData];
    updateDataSource(newDataSource);
    setEditingKey(newData[rowKey]);
  };

  const handleEdit = (record: any) => {
    const recordKey = record[rowKey];
    setOriginalData({ ...originalData, [recordKey]: { ...record } });
    setEditingKey(recordKey);
  };

  const handleSave = () => {
    const editingRecord = dataSource.find((record) => record[rowKey] === editingKey);
    if (!editingRecord) return;

    setHasAttemptedSave(true);

    if (!validateEditingRow(editingRecord)) return;

    clearEditingState(editingKey);
  };

  const handleCancel = () => {
    const recordKey = editingKey;
    const originalRecord = originalData[recordKey];

    let newDataSource: any[];
    if (originalRecord) {
      // 恢复原始数据
      newDataSource = dataSource.map((item) => (item[rowKey] === recordKey ? { ...originalRecord } : item));
    } else {
      // 新增行则删除
      newDataSource = dataSource.filter((item) => item[rowKey] !== recordKey);
    }

    updateDataSource(newDataSource);
    clearEditingState(recordKey);
  };

  const handleDelete = (key: any) => {
    const newDataSource = dataSource.filter((item) => item[rowKey] !== key);

    // 重新排序优先级
    const updatedDataSource = hasPriority
      ? newDataSource.map((item, index) => ({ ...item, priority: index + 1 }))
      : newDataSource;

    updateDataSource(updatedDataSource);

    // 如果删除的是正在编辑的行，清除编辑状态
    if (key === editingKey) {
      clearEditingState(key);
    }
  };

  // 移动行调整优先级
  const handleMoveRow = (record: any, direction: 'up' | 'down') => {
    const currentIndex = dataSource.findIndex((item) => item[rowKey] === record[rowKey]);
    if (currentIndex === -1) return;

    const newIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1;
    if (newIndex < 0 || newIndex >= dataSource.length) return;

    // 交换位置并重新排序优先级
    const newDataSource = [...dataSource];
    [newDataSource[currentIndex], newDataSource[newIndex]] = [newDataSource[newIndex], newDataSource[currentIndex]];

    const updatedDataSource = newDataSource.map((item, index) => ({
      ...item,
      priority: index + 1,
    }));

    updateDataSource(updatedDataSource);
  };

  const handleCellChange = (record: any, dataIndex: string, value: any) => {
    const newDataSource = dataSource.map((item) =>
      item[rowKey] === record[rowKey] ? { ...item, [dataIndex]: value } : item,
    );
    updateDataSource(newDataSource);
  };

  const renderCell = (text: any, record: any, dataIndex: string, column: any) => {
    // 优先级字段始终不可编辑
    if (dataIndex === 'priority' || disabled || !isEditing(record)) {
      return text;
    }

    // 只在尝试保存后才显示验证错误
    const hasError =
      hasAttemptedSave && column.required && record[rowKey] === editingKey && isFieldEmpty(record[dataIndex]);

    const commonProps = {
      value: text,
      onChange: (val: any) => handleCellChange(record, dataIndex, val),
      className: 'editable-table-full-width',
      status: (hasError ? 'error' : undefined) as 'error' | undefined,
    };

    switch (column.type) {
      case 'select':
        return (
          <Select
            {...commonProps}
            options={column.options}
            placeholder={`${t('common', 'pleaseSelect')} ${column.title}`}
          />
        );

      case 'number':
        return <InputNumber {...commonProps} placeholder={`${t('common', 'pleaseInput')} ${column.title}`} />;

      case 'date':
        return <DatePicker {...commonProps} placeholder={`${t('common', 'pleaseSelect')} ${column.title}`} />;

      default:
        return (
          <Input
            value={text}
            onChange={(e) => handleCellChange(record, dataIndex, e.target.value)}
            placeholder={`${t('common', 'pleaseInput')} ${column.title}`}
            status={(hasError ? 'error' : undefined) as 'error' | undefined}
          />
        );
    }
  };

  const renderOperationButtons = (record: any, editing: boolean) => {
    const recordKey = record[rowKey];

    if (editing) {
      return (
        <Space size="small">
          <Tooltip title={t('common', 'save')}>
            <Button
              type="link"
              icon={<SaveOutlined />}
              onClick={handleSave}
              size="small"
              className="editable-table-save-btn"
            />
          </Tooltip>
          <Tooltip title={t('common', 'cancel')}>
            <Button
              type="link"
              icon={<CloseOutlined />}
              onClick={handleCancel}
              size="small"
              className="editable-table-cancel-btn"
            />
          </Tooltip>
        </Space>
      );
    }

    const currentIndex = dataSource.findIndex((item) => item[rowKey] === recordKey);

    return (
      <Space size="small">
        {hasPriority && (
          <>
            <Tooltip title={t('common', 'up')}>
              <Button
                type="link"
                icon={<ArrowUpOutlined />}
                onClick={() => handleMoveRow(record, 'up')}
                size="small"
                disabled={currentIndex === 0}
                className={currentIndex === 0 ? 'editable-table-arrow-btn-disabled' : 'editable-table-arrow-btn-active'}
              />
            </Tooltip>
            <Tooltip title={t('common', 'down')}>
              <Button
                type="link"
                icon={<ArrowDownOutlined />}
                onClick={() => handleMoveRow(record, 'down')}
                size="small"
                disabled={currentIndex === dataSource.length - 1}
                className={
                  currentIndex === dataSource.length - 1
                    ? 'editable-table-arrow-btn-disabled'
                    : 'editable-table-arrow-btn-active'
                }
              />
            </Tooltip>
          </>
        )}
        <Tooltip title={t('common', 'edit')}>
          <Button type="link" icon={<EditOutlined />} onClick={() => handleEdit(record)} size="small" />
        </Tooltip>
        <Popconfirm
          title={t('common', 'confirmDelete')}
          onConfirm={() => handleDelete(recordKey)}
          okText={t('common', 'confirm')}
          cancelText={t('common', 'cancel')}
          zIndex={9999}
        >
          <Button type="link" danger icon={<DeleteOutlined />} size="small" className="editable-table-delete-btn" />
        </Popconfirm>
      </Space>
    );
  };

  const columns = [
    ...(config?.columns?.map((column) => ({
      title: column.required ? (
        <span>
          <span className="editable-table-required-mark">*</span>
          {column.title}
        </span>
      ) : (
        column.title
      ),
      dataIndex: column.dataIndex,
      width: column.width,
      render: (text: any, record: any) => renderCell(text, record, column.dataIndex, column),
    })) || []),
    {
      title: t('common', 'operation'),
      width: hasPriority ? 180 : 120,
      render: (_: any, record: any) => {
        if (disabled) return null;
        return renderOperationButtons(record, isEditing(record));
      },
    },
  ];

  const canAdd = !config?.maxRows || dataSource.length < config.maxRows;
  const hasUnsavedData = editingKey !== '';

  return (
    <div>
      <Table dataSource={dataSource} columns={columns} pagination={false} size="small" rowKey={rowKey} />
      {!disabled && canAdd && (
        <Button
          type="dashed"
          onClick={handleAdd}
          icon={<PlusOutlined />}
          className="editable-table-add-btn"
          disabled={hasUnsavedData}
        >
          {config?.addButtonText || t('common', 'create')}
        </Button>
      )}
    </div>
  );
};

export default EditableTable;
